package managedbean.CRM.SaleOrder; 
 
import entity.CRM.LineItem;
import entity.CRM.SaleOrder;
import entity.Employee;
import entity.Product;
import javax.faces.event.ActionEvent;
import java.io.IOException;
import java.io.Serializable;
import java.util.Calendar;
import java.util.List; 
import javax.ejb.EJB; 
import javax.ejb.EJBException;
import javax.el.ELContext;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean; 
import javax.faces.bean.ViewScoped; 
import javax.faces.context.FacesContext;
import managedbean.Controller;
import session.stateless.CRM.SaleOrderBeanLocal;
import session.stateless.FRM.CreditAccountBeanLocal;
import session.stateless.MRP.ATPCheck.ATPCheckSessionBeanLocal;
import session.stateless.MRP.SaleForecast.SaleFigureBeanLocal;
import session.stateless.MRP.SaleOrderProcess.SOProcessLocal;
import session.stateless.ProductBeanLocal;
 
@ManagedBean(name="viewSaleOrder")
@ViewScoped 
public class ViewSaleOrderManagerBean implements Serializable{ 
    @EJB 
    private SaleOrderBeanLocal saleOrderBeanLocal; 
    @EJB
    private CreditAccountBeanLocal creditAccountBeanLocal;
    @EJB
    private ATPCheckSessionBeanLocal ATPCheckSessionBeanLocal;
    @EJB
    private SOProcessLocal SOProcessLocal;
    
    @EJB
    private SaleFigureBeanLocal saleFigureBeanLocal;
    
    @EJB
    private ProductBeanLocal productBeanLocal;
    
    private SaleOrder selectedSaleOrder;
    private List<LineItem> lineItems;
    private String statusMessage;
    
    public ViewSaleOrderManagerBean() { 
    } 
 
 
    public List<SaleOrder> getSaleOrders() throws EJBException
    { 
        ELContext elContext = FacesContext.getCurrentInstance().getELContext();
        Controller controller = (Controller) FacesContext.getCurrentInstance().getApplication().getELResolver().getValue(elContext, null, "controller");
        Employee executive = controller.getEmployee();
        List<SaleOrder> temp = saleOrderBeanLocal.getSaleOrders(executive.getEmployeeId());
        if (!temp.isEmpty())
            System.out.println("heher");
        return temp;

    } 
    
    public SaleOrder getSelectedSaleOrder() {
        return selectedSaleOrder;
    }

    public void setSelectedSaleOrder(SaleOrder selectedSaleOrder) {
        this.selectedSaleOrder = selectedSaleOrder;
    }

    public List<LineItem> getLineItems() {
        return lineItems;
    }

    public void setLineItems(List<LineItem> lineItems) {
        this.lineItems = lineItems;
    }

    public SaleOrderBeanLocal getSaleOrderBeanLocal() {
        return saleOrderBeanLocal;
    }

    public void setSaleOrderBeanLocal(SaleOrderBeanLocal saleOrderBeanLocal) {
        this.saleOrderBeanLocal = saleOrderBeanLocal;
    }

    public String getStatusMessage() {
        return statusMessage;
    }

    public void setStatusMessage(String statusMessage) {
        this.statusMessage = statusMessage;
    }
    
    
        
    public void editSaleOrder(ActionEvent event) throws IOException
    {
        selectedSaleOrder = this.getSelectedSaleOrder();
        if(selectedSaleOrder != null)
        {
            FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("selectedSaleOrder", selectedSaleOrder);
            FacesContext.getCurrentInstance().getExternalContext().redirect("editSaleOrder.xhtml");      
        }
    }
    
    
    
    public void deleteSaleOrder(ActionEvent event) throws IOException
    {
       selectedSaleOrder = this.getSelectedSaleOrder();

        try
        {
            saleOrderBeanLocal.deleteSaleOrder(selectedSaleOrder.getId());
            FacesContext.getCurrentInstance().getExternalContext().redirect("viewSaleOrder.xhtml");
        }
        catch(Exception ex){
            ex.printStackTrace();
        }
    }
    
    public void checkCredit(ActionEvent event) throws IOException
    {
        selectedSaleOrder = this.getSelectedSaleOrder();
        if (selectedSaleOrder.getStateSaleOrder()==SaleOrder.StateSaleOrder.Confirmed)        
            statusMessage="Invalid: Order confirmed previously";
        else
        {
            Double temp =creditAccountBeanLocal.isPass_checkCredit(selectedSaleOrder.getId());
            if (temp>0)
                statusMessage = "Pass!";
            else
                statusMessage ="Fail: Lack $ "+temp+"";
        }
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO,  "Result: " +statusMessage + "." , ""));         
        
    }
    
    public void checkATP(ActionEvent event) throws IOException
    {
        selectedSaleOrder = this.getSelectedSaleOrder();
        if (selectedSaleOrder.getStateSaleOrder()==SaleOrder.StateSaleOrder.Confirmed)        
            statusMessage="Invalid: Order confirmed previously";
        else
        {
            long leadTime = ATPCheckSessionBeanLocal.getLeadTimeSO(selectedSaleOrder.getId());
            if (leadTime==-1)
                statusMessage = "Fail: Current production for this month and next month is unable to process the order. Please reduce the order or wait for next month";
            else if (leadTime ==0)
                statusMessage = "Pass: The order can be executed immediately";
            else if (leadTime>0)
                statusMessage = "Working days required is "+leadTime+"";                
        }
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO,  "Result: " +statusMessage + "." , ""));         
        
    }
    
    public void confirmOrder (ActionEvent event) throws IOException
    {
        selectedSaleOrder = this.getSelectedSaleOrder();
        if (selectedSaleOrder.getStateSaleOrder()==SaleOrder.StateSaleOrder.Confirmed)
            statusMessage="Invalid: Order confirmed previously";
        else
        {
            Double temp =creditAccountBeanLocal.isPass_checkCredit(selectedSaleOrder.getId());
            long leadTime = ATPCheckSessionBeanLocal.getLeadTimeSO(selectedSaleOrder.getId());
            
            if ( temp<0)
            {
                statusMessage="Invalid: Credit check failed.";
            }
            else if (leadTime==-1)
            {
                statusMessage="Invalid: ATP Check failed.";
            }
            else
            {
                System.out.println("test1: viewSO b4 call processSaleOrder");
                //Step1 :Sale order processing
                SOProcessLocal.processSaleOrder(selectedSaleOrder.getId());
                
                //Step 2: Update customer's account
                creditAccountBeanLocal.modifyCreditAccount_AddConfirmedSaleOrder(selectedSaleOrder.getId());
                
                
                //Last step: update status to Confirmed and show result
                saleOrderBeanLocal.updateStatus(selectedSaleOrder.getId(), SaleOrder.StateSaleOrder.Confirmed);
                statusMessage="Order has been confirmed. Outstanding credit has been updated to "+saleOrderBeanLocal.findSaleOrder(selectedSaleOrder.getId()).getCustomer().getCreditAccount().getOutstandingCredit();
                
                //create entry in the sale figure database
                int year = Calendar.getInstance().get(Calendar.YEAR);
                int month = Calendar.getInstance().get(Calendar.MONTH);
                for (LineItem li:selectedSaleOrder.getLineItems()){
                    Product product = productBeanLocal.findProduct(li.getProductPrice().getProductType());
                    saleFigureBeanLocal.updateSaleFigure(year, month, product, li.getLineItemQuantity(), 0);
                }
                
            }
            
        }
        
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO,  "Result: " +statusMessage + "" , ""));         
    }
} 